package com.libui.webview.jsinterface

import android.util.TypedValue
import android.webkit.JavascriptInterface
import com.google.gson.reflect.TypeToken
import com.libbase.Weak
import com.libbase.cast
import com.libbase.extension.appVersion
import com.libbase.utils.JsonUtils
import com.libui.utils.ColorUtils
import com.libui.utils.WindowUtils
import com.libui.webview.WebViewEx
import com.libui.webview.jsinterface.handlers.*

class JSInterface(webView: WebViewEx) {
    companion object {
        const val key: String = "messageHandlers"
    }

    private var webView: WebViewEx? by Weak { webView }

    private val webViewHandlers: Map<String, WebViewHandlerInterface> = mutableMapOf(
        CloseDialogHandler.id to CloseDialogHandler(),
        RequestHandler.id to RequestHandler(),
        AlertHandler.id to AlertHandler(),
        ConfirmHandler.id to ConfirmHandler(),
        SetRightMenusHandler.id to SetRightMenusHandler(),
        ShareHandler.id to ShareHandler(),
        WebViewMessageHandler.id to WebViewMessageHandler(),
    )

    init {
        this.webView = webView
    }

    @JavascriptInterface
    fun onMessage(param: String) {
        val mapType = object : TypeToken<Map<String, Any>>() {}.type
        val values: Map<String, Any> = JsonUtils.json.fromJson(param, mapType)

        val id = values["id"] as? String ?: return

        val handler = webViewHandlers[id] ?: return

        handler.handle(webView, cast(values["params"]))
    }

    @JavascriptInterface
    fun getStatusBarHeight(): Int {
        return webView?.context?.let { WindowUtils.instance.getStatusBarHeight(it) } ?: 0
    }

    @JavascriptInterface
    fun getAppVersion(): String {
        return webView?.context?.let {
            it.packageManager.appVersion(it.packageName)
        } ?: ""
    }

    @JavascriptInterface
    fun getPrimaryColor(): String {
        return webView?.let {
            val typedValue = TypedValue()
            it.context.theme.resolveAttribute(
                androidx.appcompat.R.attr.colorPrimary,
                typedValue,
                true
            )
            ColorUtils.toHexString(typedValue.data)
        } ?: ""
    }
}